package zack.project.trigger.listener;


import zack.project.domain.activity.model.entity.SkuRechargeEntity;
import zack.project.domain.activity.model.valobj.OrderTradeTypeVO;
import zack.project.domain.activity.service.IRaffleActivityAccountQuotaService;
import zack.project.domain.credit.model.entity.TradeEntity;
import zack.project.domain.credit.model.valobj.TradeNameVO;
import zack.project.domain.credit.model.valobj.TradeTypeVO;
import zack.project.domain.credit.service.ICreditAdjustService;

import zack.project.domain.rebate.event.SendRebateMessageEvent;

import zack.project.types.enums.ResponseCode;
import zack.project.types.event.BaseEvent;
import zack.project.types.exception.AppException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**返利消息消费者
 * @author A1793
 */
@Slf4j
@Component
public class RebateMessageCustomer {
    @Value("${spring.rabbitmq.topic.send_rebate}")
    private String topic;

    @Resource
    private IRaffleActivityAccountQuotaService raffleActivityAccountQuotaService;
    @Resource
    private ICreditAdjustService creditService;

    @RabbitListener(queuesToDeclare = @Queue("${spring.rabbitmq.topic.send_rebate}"))
    public void listener(String message) {
        try {
            BaseEvent.EventMessage<SendRebateMessageEvent.RebateMessage> messageEventMessage =
                    JSON.parseObject(message,
                            new TypeReference<BaseEvent.EventMessage<SendRebateMessageEvent.RebateMessage>>() {
            }.getType());
            //获得返利消息内容
            SendRebateMessageEvent.RebateMessage eventMessageData = messageEventMessage.getData();
            //解析接收到的返利的返利消息，根据返利消息中配置的返利类型进行不同处理
            switch (eventMessageData.getRebateType()) {
                //sku抽奖次数充值
                // id   behavior_type   rebate_desc     rebate_type rebate_config   state
                // 1	sign	        签到返利-sku额度	sku	        9014	        open	2024-04-30 09:32:46	2024-06-22 09:52:39
                case "sku": {
                    SkuRechargeEntity skuRechargeEntity = new SkuRechargeEntity();
                    //设置要充值的sku商品
                    //id sku    activity_id     activity_count_id   total_count total_surplus_count pay_amount
                    //1	9011	100301	        11101	            100000	    99887	            200.00	2024-03-16 11:41:09	2024-06-22 08:49:32
                    //2	9012	100301	        11102	            100000	    99885	            100.00	2024-03-16 11:41:09	2024-06-22 11:46:15
                    //3	9013	100301	        11103	            100000	    99884	            20.00	2024-03-16 11:41:09	2024-06-22 11:45:55
                    //4	9014	100301	        11104	            100000	    99866	            5.00	2024-03-16 11:41:09	2024-06-22 11:45:50
                    //四种sku商品有四种抽奖次数配置
                    skuRechargeEntity.setSku(Long.valueOf(eventMessageData.getRebateConfig()));
                    skuRechargeEntity.setUserId(eventMessageData.getUserId());
                    skuRechargeEntity.setOutBusinessNo(eventMessageData.getBizId());
                    //将充值类型设置为不需要支付(数据库表{raffle_activity_order}存储的是对用户活动账户{raffle_activity_account}抽奖次数充值的记录)
                    //当需要用积分兑换sku商品的时候，orderTradeType就是"credit_pay_trade"类型的
                    skuRechargeEntity.setOrderTradeTypeVO(OrderTradeTypeVO.rebate_no_pay_trade);
                    //走活动账户调额服务
                    raffleActivityAccountQuotaService.createOrder(skuRechargeEntity);
                    log.info("监听用户行为返利消息，sku返利成功 userId:{}", eventMessageData.getUserId());
                }
                break;
                //积分充值
                case "integral": {
                    TradeEntity tradeEntity = new TradeEntity();
                    tradeEntity.setUserId(eventMessageData.getUserId());
                    tradeEntity.setOutBusinessNo(eventMessageData.getBizId());
                    tradeEntity.setTradeTypeVO(TradeTypeVO.FORWARD);
                    tradeEntity.setTradeNameVO(TradeNameVO.REBATE);
                    tradeEntity.setAmount(new BigDecimal(eventMessageData.getRebateConfig()));
                    creditService.createOrder(tradeEntity);
                    log.info("监听用户行为返利消息，积分返利成功 userId:{}", eventMessageData.getUserId());
                }
                break;
            }
        } catch (AppException e) {
            //如果该行为已经有返利了则捕获唯一索引冲突(可能是因为该消息再别的应用被消费),不抛出错误不让mq重新投递消息或本地重试
            if (ResponseCode.INDEX_DUP.getCode().equals(e.getCode())) {
                log.warn("监听用户行为返利消息，消费重复 topic: {} message: {}", topic, message, e);
                return;
            }
            //如果是参数错误则捕获该错误不抛出异常，不让mq重新投递或在本地重试
            else if(ResponseCode.ILLEGAL_PARAMETER.getCode().equals(e.getCode())) {
                log.warn("参数错误 topic: {} message: {}", topic, message, e);
                return;
            }
            throw e;
        } catch (Exception e) {
            log.error("监听用户行为返利消息，消费失败 topic: {} message: {}", topic, message, e);
            throw e;
        }


    }

}
